/*
package com.ld.security.common.mybatis.base.service;

import cn.hutool.core.lang.Console;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ld.security.common.core.base.LimitPo;
import com.ld.security.common.core.base.OrderByPo;
import com.ld.security.common.core.base.SuperPo;
import com.ld.security.common.core.base.column.ListJson;
import com.ld.security.common.core.base.column.ListString;
import com.ld.security.common.core.base.column.MapJson;
import com.ld.security.common.core.base.column.SuperColumn;
import com.ld.security.common.core.constant.CSuperConstant;
import com.ld.security.common.core.exception.ApiException;
import com.ld.security.common.core.util.GenericUtil;
import com.ld.security.common.core.util.JsonUtil;
import com.ld.security.common.core.util.ReflectionUtil;
import com.ld.security.common.core.util.StringUtil;
import com.ld.security.common.mybatis.anno.*;
import com.ld.security.common.mybatis.base.entity.ESwitchEntity;
import com.ld.security.common.mybatis.base.entity.LabelMap;
import com.ld.security.common.mybatis.base.entity.SuperEntity;
import com.ld.security.common.mybatis.base.mapping.SqlMapping;
import com.ld.security.common.mybatis.base.mapping.SuperMapping;
import com.ld.security.common.mybatis.base.po.PagePo;
import com.ld.security.common.mybatis.base.vo.PageVo;
import com.ld.security.common.mybatis.base.vo.ProxyVo;
import com.ld.security.common.mybatis.constant.SqlCondition;
import com.ld.security.common.mybatis.core.wrapper.EntityWrapper;
import com.ld.security.common.mybatis.event.DeleteEvent;
import com.ld.security.common.mybatis.event.QueryEvent;
import com.ld.security.common.mybatis.event.SaveEvent;
import com.ld.security.common.mybatis.wrapper.SimpQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;


@Component
public class ProxyServiceImpl2 implements IProxyService {

    @Autowired(required = false)
    private List<SuperMapping> superMappingList;

    @Autowired
    SqlMapping sqlMapping;


    @Autowired(required = false)
    List<SaveEvent> saveEvents = Arrays.asList();

    @Autowired(required = false)
    List<DeleteEvent> deleteEvents = Arrays.asList();;

    @Autowired(required = false)
    List<QueryEvent> queryEvents = Arrays.asList();;




    */
/**
     * 开启开关
     * @param e
     * @return
     *//*

    public int proxyOpenSwitch(ESwitchEntity e){
            if(ReflectionUtil.isNotNull(e.getSwitchValue())){
                return 0;
            }
            SuperMapping mapping =  this.getService(e.getClass());

        ESwitchEntity se =   ReflectionUtil.newInstance(e.getClass());
        se.setSwitchValue(false);

        UpdateWrapper uw = new UpdateWrapper<>().eq("switch_code",e.getSwitchCode());
        return mapping.update(se,uw);
    }


    private SuperMapping getService(Field field){

        Class clazz= this.getFieldClass(field);

        return getService(clazz);
    }

    public SuperMapping getService(Class clazz){
        if(superMappingList == null){
            ApiException.throw400("异常superMappingList");
        }
        for (SuperMapping superMapping : superMappingList) {
            if(clazz.isAssignableFrom( superMapping.getEntityClass())){
                return superMapping;
            }
        }
        //ApiException.throw400("异常实体类:"+clazz);
        return null;
    }
    private void  invokeSetter(Object obj,String key,String groupKey,List vals){
        Field field =  ReflectionUtils.findField(obj.getClass(),key);
        if(List.class.isAssignableFrom(field.getType())){
            List list =  ReflectionUtil.invokeGetter(obj,key);
            if(list == null){
                list = new LinkedList();
                ReflectionUtil.invokeSetter(obj,key,list);
            }
            list.addAll(vals);
        }else if(Map.class.isAssignableFrom(field.getType())){
            if(StringUtil.isNull(groupKey)){
                ApiException.throw400("分组key为空");
            }
            Class clazz =  GenericUtil.getGeneric(field,1);
            if(List.class.isAssignableFrom(clazz)){


                Object val =  vals.stream().collect(Collectors.groupingBy(v -> {
                    Object vc =   ReflectionUtil.invokeGetter(v,groupKey);
                    if(vc == null){
                        vc="默认";
                    }
                    return vc;
                }));
                ReflectionUtil.invokeSetter(obj,key,val);
            }else{
                Map map =  new HashMap<>();
                for (Object val : vals) {
                    Object k =  ReflectionUtil.invokeGetter(val,groupKey);
                    map.put(k,val);
                }
                ReflectionUtil.invokeSetter(obj,key,map);
            }

        } else if(!vals.isEmpty()){
            ReflectionUtil.invokeSetter(obj,key,vals.get(0));
        }else{
            ApiException.throw400("异常数据,结果为空");
        }
    }

    */
/**
     * 在执行过程中,发现了泛型集合，则递归
     * 基本数据，则返回
     * @param
     * @return
     *//*

    private List<?> invokeGetter(Object root,    List<String> keys ){


        List<Object> parent = Arrays.asList(root);

        for(int i = 0;i<keys.size();i++){
            List children =  new LinkedList<>();

            for (Object node : parent) {
                Object v = ReflectionUtil.invokeGetter(node,keys.get(i));
                if(v == null){
                    continue;
                }
                if(Collection.class.isAssignableFrom(v.getClass())){
                   Collection vs = (Collection) v;
                    for (Object o : vs) {
                        if(o instanceof Collection){
                            children.addAll((Collection) o);
                        }else{
                            children.add(o);
                        }

                    }

                }else if(Map.class.isAssignableFrom(v.getClass())){
                    Map map =(Map)v;
                    for (Object o : map.values()) {
                        if(o instanceof Collection){
                            children.addAll((Collection)o);
                        }else{
                            children.add(o);
                        }
                    }

                } else {
                    children.add(v);
                }

            }
            parent=children;


        }

        return parent;

    }



    private List<?> invokeGetter(Object e,    String string ) {
        String[] keys =string.split(ReflectionUtil.sp_prefix);

        ListString listString =   new ListString(keys);
        return this.invokeGetter(e,listString);
    }


    private List<SqlKey> getSqlKeys(Field field){
        SqlKey sqlKey = field.getAnnotation(SqlKey.class);
        SqlKeys sqlKeys = field.getAnnotation(SqlKeys.class);
        if(sqlKey != null){
            return Arrays.asList(sqlKey);
        }else if(sqlKeys != null){
            return Arrays.asList(sqlKeys.value());
        }
     //   return null;
        throw new RuntimeException("异常查询条件");
    }


    private Class getFieldClass(Field field){
        if(List.class.isAssignableFrom(field.getType())){
            return GenericUtil.getGeneric(field,0);

        }else if(Map.class.isAssignableFrom(field.getType())){
            Class fieldClass =  GenericUtil.getGeneric(field,1);
            if(Collection.class.isAssignableFrom(fieldClass)){
                Class fieldClass2 =  GenericUtil.getGeneric(field,1,0);
                return fieldClass2;
            }else{
                return fieldClass;
            }
        }
        else{
            return field.getType();
        }
    }


    @Override
    public Object proxyQuery(Object obj){
        for (Field field : ReflectionUtil.getAllDeclaredFields(obj.getClass())) {
            QueryKey proxyKey =   field.getAnnotation(QueryKey.class);

            if(proxyKey == null){
                continue;
            }
            Class fieldType = this.getFieldClass(field);
            SimpQueryWrapper wrapper =  new SimpQueryWrapper(fieldType);
            List<SqlKey> sqlKeys =  this.getSqlKeys(field);


            boolean b=true;
            for (SqlKey sqlKey : sqlKeys) {
                // SuperMapping mapping =  this.getService(field);
                List cols =  invokeGetter(obj,sqlKey.valueField());
                SqlCondition sqlCondition =  sqlKey.value();

                Object v =cols;
                if(cols.size() == 0){
                    continue;
                    // ApiException.throw400("异常数据："+v);
                }
                else if(sqlCondition == SqlCondition.eq){
                    v = cols.get(0);
                    //sqlCondition=SqlCondition.eq;
                }


                String columnName=null;

*/
/*
                if(SuperVo.class.isAssignableFrom(fieldType)){
                    Field tarField = ReflectionUtil.findField(fieldType,sqlKey.name());
                    SqlKey sqlKey1 = tarField.getAnnotation(SqlKey.class);

                    if(sqlKey != null){
                        columnName = sqlKey.name();
                    }
                    if(StringUtil.isNull(columnName)){
                        columnName = field.getName();
                    }
                }else{*//*

                    columnName =  sqlKey.name();
                    if(StringUtil.isNull(columnName)){
                        columnName = field.getName();
                    }
               // }

                columnName =StringUtil.javaToColumn(columnName);
                wrapper.where(columnName, sqlCondition,v,sqlKey.and());
                b=false;
            }

            if(b){
                continue;
            }
            List list = null;

            try{
                list = this.all(wrapper,fieldType).getList();

            }catch (Exception e){
                e.printStackTrace();
            }




            invokeSetter(obj,field.getName(),proxyKey.groupKey(),list);
        }

    for (QueryEvent queryEvent : queryEvents) {
        queryEvent.queryAfter(obj);
    }


        return  obj;
    }


    */
/**
     * 如果是集合，返回数组
     * @param field
     * @param val
     * @return
     *//*

    private List<SuperEntity> getList(Field field ,Object val){
        Class clazz = field.getType();
        List list = new LinkedList<>();
        if(Map.class.isAssignableFrom(clazz)){
            Class mapClazz =  GenericUtil.getGeneric(field,1);
            if(Collection.class.isAssignableFrom(mapClazz)){
                Map<Object,Collection<SuperEntity>> map = (Map)val;
                for (Collection<SuperEntity> vs : map.values()) {
                    list.addAll(vs);
                }
            }else if(SuperEntity.class.isAssignableFrom(mapClazz)){
                Map<Object,SuperEntity> map = (Map)val;
                Collection<SuperEntity> vs =  map.values();
                list.addAll(vs);
            }
        }else if(Collection.class.isAssignableFrom(clazz)){
            Collection cols =(Collection) val;
            list.addAll(cols);
        }else if(SuperEntity.class.isAssignableFrom(clazz)){
            list.add(val);
        }
        return list;
    }




    @Override
    public Object proxySave(Object obj) {

        if(obj instanceof ProxyVo){
            ProxyVo vo =(ProxyVo) obj;
            vo.saveBefore();
        }

        for (Field field : ReflectionUtil.getAllDeclaredFields(obj.getClass())) {
            SaveKey saveKey =  field.getAnnotation(SaveKey.class);

            if(saveKey == null){
                continue;
            }


            SuperMapping mapping = this.getService(field);
            Object val =  ReflectionUtil.invokeGetter(obj,field.getName());
            Collection<SuperEntity> cols = this.getList(field,val);
            for (SuperEntity col : cols) {
                if(StringUtil.isNotNull(saveKey.name())){
                    Object v =  ReflectionUtil.invokeGetter(obj, saveKey.valueField());
                    ReflectionUtil.invokeSetter(col,saveKey.name(),v);
                }


                for (SaveEvent saveEvent : saveEvents) {
                    saveEvent.saveBefore(col);
                }

                mapping.save(col);

                for (SaveEvent saveEvent : saveEvents) {
                    saveEvent.saveAfter(col);
                }
            }

        }
        if(obj instanceof ProxyVo){
            ProxyVo vo =(ProxyVo) obj;

        }

            return obj;
    }

    @Override
    public Object proxyRemove(Object obj) {
        for (Field field : ReflectionUtil.getAllDeclaredFields(obj.getClass())) {
            RemoveKey removeKey =  field.getAnnotation(RemoveKey.class);
            if(removeKey == null){
                continue;
            }
            Class clazz =  removeKey.value();
            if(clazz.equals(Object.class)){
                clazz  = this.getFieldClass(field);
            }
            SuperMapping mapping = this.getService(clazz);
            Object val =  ReflectionUtil.invokeGetter(obj,field.getName());
            if(val == null){
                continue;
            }
            Collection<SuperEntity> cols = this.getList(field,val);
            if(cols.isEmpty()){
                continue;
            }

            List<String> ids =  cols.stream().map(v
                    -> {
                if(v instanceof SuperEntity){
                    return ReflectionUtil.invokeGetter(v,"id");
                }
                return ((Object) v).toString();

            }).collect(Collectors.toList());

            EntityWrapper ew = EntityWrapper.newInstance();
            ew.in(StringUtil.javaToColumn(removeKey.name()),ids);

      for (DeleteEvent deleteEvent : deleteEvents) {
        for (SuperEntity col : cols) {
            deleteEvent.deletebBefore(col);
        }
      }
            mapping.remove(ew);
            for (DeleteEvent deleteEvent : deleteEvents) {
                for (SuperEntity col : cols) {
                    deleteEvent.deleteAfter(col);
                }
            }
           // mapping.remove(ew);

        }
        return obj;
    }

    @Override
    public Object proxyLabel(Object obj) {
        for (Field field : ReflectionUtil.getAllDeclaredFields(obj.getClass())) {
            LabelKeys labelKey =  field.getAnnotation(LabelKeys.class);
            if(labelKey == null){
                continue;
            }
            Object labels = null;
            if(CSuperConstant.EnSuperEnum.class.isAssignableFrom(field.getType())){
                CSuperConstant.EnSuperEnum e = ReflectionUtil.invokeGetter(obj,field.getName());
                if(e == null){
                    continue;
                }
                labels = e.getLabel();
                if(obj instanceof LabelMap){
                    LabelMap labelMap = (LabelMap)obj;
                    MapJson map = labelMap.getLabelMap();
                    if(map == null){
                        map = new MapJson();
                        labelMap.setLabelMap(map);
                    }
                    map.put(field.getName(),labels);
                }
            }else{

                SimpQueryWrapper ew =   new SimpQueryWrapper(labelKey.value());

                //SuperMapping mapping =  this.getService(labelKey.value());
                //获取指定值，会放在labelMap中
                String name=labelKey.valueField();
                if(StringUtil.isNull(name)){
                    //拿自身作为值，放到map中
                    name=field.getName();
                }
                List cols =  invokeGetter(obj,name);
                if(cols.isEmpty()){
                    continue;
                }
                ew.where(labelKey.name(),SqlCondition.in,cols);

                List list =  this.all(ew,labelKey.value()).getList();

                // EntityWrapper ew = EntityWrapper.of(new IdsPo(cols));

                //List<?> list =  mapping.all(ew);
                for (LabelKey key : labelKey.labels()) {
                    if(Collection.class.isAssignableFrom(field.getType())){
                        labels = list.stream().map(val -> {
                            return  ReflectionUtil.invokeGetter(val,key.sourceKey());
                        }).collect(Collectors.toList());


                    }else if(!list.isEmpty()){
                        labels =  ReflectionUtil.invokeGetter(list.get(0),key.sourceKey());

                    }else{

                        Console.error("数据集合为空");
                    }

                    if(StringUtil.isNull(key.targetKey())){
                        if(obj instanceof LabelMap){
                            LabelMap labelMap = (LabelMap)obj;
                            MapJson map = labelMap.getLabelMap();
                            if(map == null){
                                map = new MapJson();
                                labelMap.setLabelMap(map);
                            }
                            map.put(field.getName(),labels);
                        }
                    }else{
                        ReflectionUtil.invokeSetter(obj,key.targetKey(),labels);

                    }


                }

                //ReflectionUtil.invokeSetter(obj,field.getName(),labels);
            }




        }
        return obj;
    }




    @Override
    public <E  > PageVo<E> page(PagePo<E> po) {
        SimpQueryWrapper ew =   new SimpQueryWrapper(po.getQuery());
        Object query =  po.getQuery();
        Page page =  this.toPage(po);
        sqlMapping.page(page,ew);
        return this.toPageVo(page,query.getClass());
    }

    @Override
    public <E> List<E> all(E query) {
        SimpQueryWrapper ew =   new SimpQueryWrapper(query);
        List list =  sqlMapping.all(ew);
        return (List<E>)this.toPageVo(list,query.getClass()).getList();
    }

    public <E> PageVo<E> all(SimpQueryWrapper ew, Class clazz) {
        List list =  sqlMapping.all(ew);
        return this.toPageVo(list,clazz);
    }

    public Page toPage(SuperPo po) {
        Page page = new Page();

        if(po instanceof LimitPo){
            LimitPo p =(LimitPo) po;
            page.setCurrent(p.getPageNumber());
            page.setSize(p.getPageSize());

        }
        if(po instanceof OrderByPo){
            OrderByPo orderByPo = (OrderByPo)po;
            if(orderByPo.isAsc()){
                page.setAsc(orderByPo.getOrderBy());
            }else{
                page.setDesc(orderByPo.getOrderBy());
            }
        }
        return page;
    }


    private void fomat(Object obj,Class clazz){
        for (Field field : ReflectionUtil.getAllDeclaredFields(clazz)) {
          if(!SuperColumn.class.isAssignableFrom(field.getType())){
              continue;
          }
          Object val =  ReflectionUtil.invokeGetter(obj,field.getName());
          if(val == null){
              continue;
          }
           Object value =null;
            if(ListString.class.isAssignableFrom(field.getType())){


                value =  new ListString(val.toString());

            }else if(MapJson.class.isAssignableFrom(field.getType())){

                value = JsonUtil.toObject(val.toString(),MapJson.class);

            }else if(ListJson.class.isAssignableFrom(field.getType())){
                value =  JsonUtil.toObject(val.toString(),ListJson.class);
            }
            ReflectionUtil.invokeSetter(obj,field.getName(), value);
        }
    }

    protected <C> PageVo<C> toPageVo(Page page,Class clazz){
        PageVo<C> vo = new PageVo<>();
        vo.setTotal(page.getTotal());
        for (Object o : page.getRecords()) {
            this.fomat(o,clazz);
        }


        List list =  JsonUtil.clone(page.getRecords(),List.class,clazz);

        vo.setList(list);
        return vo;
    }


    protected <C> PageVo<C> toPageVo(List page,Class clazz){

        PageVo<C> vo = new PageVo<>();

        vo.setTotal(page.size());
        for (Object o : page) {
            this.fomat(o,clazz);
        }
        List list =  JsonUtil.clone(page,List.class,clazz);
        vo.setList(list);
        return vo;
    }

}
*/
